<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- 
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License. 
-->
<html>
<head>
    <link type="text/css" rel="stylesheet" href="https://struts.apache.org/css/default.css">
    <style type="text/css">
        .dp-highlighter {
            width:95% !important;
        }
    </style>
    <style type="text/css">
        .footer {
            background-image:      url('https://cwiki.apache.org/confluence/images/border/border_bottom.gif');
            background-repeat:     repeat-x;
            background-position:   left top;
            padding-top:           4px;
            color:                 #666;
        }
    </style>
    <link href='https://struts.apache.org/highlighter/style/shCoreStruts.css' rel='stylesheet' type='text/css' />
    <link href='https://struts.apache.org/highlighter/style/shThemeStruts.css' rel='stylesheet' type='text/css' />
    <script src='https://struts.apache.org/highlighter/js/shCore.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushPlain.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushXml.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJava.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJScript.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushGroovy.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushBash.js' type='text/javascript'></script>
    <script type="text/javascript">
        SyntaxHighlighter.defaults['toolbar'] = false;
        SyntaxHighlighter.all();
    </script>
    <script type="text/javascript" language="javascript">
        var hide = null;
        var show = null;
        var children = null;

        function init() {
            /* Search form initialization */
            var form = document.forms['search'];
            if (form != null) {
                form.elements['domains'].value = location.hostname;
                form.elements['sitesearch'].value = location.hostname;
            }

            /* Children initialization */
            hide = document.getElementById('hide');
            show = document.getElementById('show');
            children = document.all != null ?
                    document.all['children'] :
                    document.getElementById('children');
            if (children != null) {
                children.style.display = 'none';
                show.style.display = 'inline';
                hide.style.display = 'none';
            }
        }

        function showChildren() {
            children.style.display = 'block';
            show.style.display = 'none';
            hide.style.display = 'inline';
        }

        function hideChildren() {
            children.style.display = 'none';
            show.style.display = 'inline';
            hide.style.display = 'none';
        }
    </script>
    <title>Profiling</title>
</head>
<body onload="init()">
<table border="0" cellpadding="2" cellspacing="0" width="100%">
    <tr class="topBar">
        <td align="left" valign="middle" class="topBarDiv" align="left" nowrap>
            &nbsp;<a href="home.html">Home</a>&nbsp;&gt;&nbsp;<a href="guides.html">Guides</a>&nbsp;&gt;&nbsp;<a href="core-developers-guide.html">Core Developers Guide</a>&nbsp;&gt;&nbsp;<a href="profiling.html">Profiling</a>
        </td>
        <td align="right" valign="middle" nowrap>
            <form name="search" action="https://www.google.com/search" method="get">
                <input type="hidden" name="ie" value="UTF-8" />
                <input type="hidden" name="oe" value="UTF-8" />
                <input type="hidden" name="domains" value="" />
                <input type="hidden" name="sitesearch" value="" />
                <input type="text" name="q" maxlength="255" value="" />
                <input type="submit" name="btnG" value="Google Search" />
            </form>
        </td>
    </tr>
</table>

<div id="PageContent">
    <div class="pageheader" style="padding: 6px 0px 0px 0px;">
        <!-- We'll enable this once we figure out how to access (and save) the logo resource -->
        <!--img src="/wiki/images/confluence_logo.gif" style="float: left; margin: 4px 4px 4px 10px;" border="0"-->
        <div style="margin: 0px 10px 0px 10px" class="smalltext">Apache Struts 2 Documentation</div>
        <div style="margin: 0px 10px 8px 10px"  class="pagetitle">Profiling</div>

        <div class="greynavbar" align="right" style="padding: 2px 10px; margin: 0px;">
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=27308">
                <img src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Edit Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=27308">Edit Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">
                <img src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Browse Space"></a>
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">Browse Space</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=27308">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=27308">Add Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=27308">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add News"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=27308">Add News</a>
        </div>
    </div>

    <div class="pagecontent">
        <div class="wiki-content">
            <div id="ConfluenceContent"><p>Profiling software looks for bottlenecks in program execution. In addition to the profiling services provided by IDEs and standalone profilers, the framework provides its own internal support for profiling. </p>


<h2 id="Profiling-Profilingaspects">Profiling aspects </h2>
<p></p><p>
Struts2 profiling aspects involves the following:
</p>

<p></p><ul><li>ActionContextCleanUp</li><li>FreemarkerPageFilter</li><li>DispatcherFilter
     <ul><li>Dispatcher
             <ul><li>creation of DefaultActionProxy
                     <ul><li>creation of DefaultActionInvocation
                             <ul><li>creation of Action</li></ul>
                         </li></ul>
                 </li><li>execution of DefaultActionProxy
                     <ul><li>invocation of DefaultActionInvocation
                             <ul><li>invocation of Interceptors</li><li>invocation of Action</li><li>invocation of PreResultListener</li><li>invocation of Result</li></ul>
                         </li></ul>
                 </li></ul>
         </li></ul>
 </li></ul>


<h2 id="Profiling-Using">Using</h2>
<p>To enable profiling, first make sure that the <code>profiling</code> interceptor is applied to your action, like:</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;action ... &gt;   
   ... 
   &lt;interceptor-ref name="profiling"&gt; 
       &lt;param name="profilingKey"&gt;profiling&lt;/param&gt; 
   &lt;/interceptor-ref&gt; 
   ... 
&lt;/action&gt; 
</pre>
</div></div>

<p>Then enable profiling using one of the following methods:</p>

<h3 id="Profiling-ActivateThroughSystemproperty">Activate Through System property</h3>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[

 -Dxwork.profile.activate=true

]]></script>
</div></div>
<p></p><p>
This could be done in the container startup script eg. CATALINA_OPTS in catalina.sh
(tomcat) or using 'java -Dxwork.profile.activate=true -jar start.jar' (jetty)
</p>

<h3 id="Profiling-ActivateThroughcode">Activate Through code</h3>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[

 UtilTimerStack.setActivate(true);

]]></script>
</div></div>
<p></p><p>
This could be done in a static block, in a Spring bean with lazy-init='false',
in a Servlet with init-on-startup as some numeric value, in a Filter or
Listener's init method etc.
</p>

<h3 id="Profiling-ActivateThroughparameter">Activate Through parameter</h3>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
http://host:port/context/namespace/someAction.action?profiling=true 
</pre>
</div></div> 

<h3 id="Profiling-Changingtheactivationparametername">Changing the activation parameter name</h3>
<p>Set the <code>profilingKey</code> attribute of the <code>profiling</code> interceptor to the desired name:</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;action ... &gt;   
   ... 
   &lt;interceptor-ref name="profiling"&gt; 
       &lt;param name="profilingKey"&gt;profiling&lt;/param&gt; 
   &lt;/interceptor-ref&gt; 
   ... 
&lt;/action&gt; 
</pre>
</div></div>

<div class="confluence-information-macro confluence-information-macro-warning"><span class="aui-icon aui-icon-small aui-iconfont-error confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
<p>Profiling activation through a parameter requires <code>struts.devMode</code> to be <code>true</code>.</p></div></div>

<h2 id="Profiling-Filteringprofileinformation">Filtering profile information</h2>
<p>One could filter out the profile logging by having a System property as follows:</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
-Dxwork.profile.mintime=10000 
</pre>
</div></div>
<p> With this <code>xwork.profile.mintime</code> property, one could only log profile information when its execution time exceed those specified in <code>xwork.profile.mintime</code> system property. If no such property is specified, it will be assumed to be 0, hence all profile information will be logged.</p>

<h2 id="Profiling-Writeprofilingcode">Write profiling code</h2>
<p>One could extend the profiling feature provided by Struts2 in their web application as well. </p>

<h3 id="Profiling-UsingUtilTimerStack'spushandpop">Using UtilTimerStack's push and pop</h3>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
String logMessage = "Log message"; 
UtilTimerStack.push(logMessage); 
try { 
    // do some code 
} finally { 
    UtilTimerStack.pop(logMessage); // this needs to be the same text as above 
} 
</pre>
</div></div>

<h3 id="Profiling-UsingaUtilTimerStack'sProfileBlocktemplate">Using a UtilTimerStack's ProfileBlock template</h3>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
String result = UtilTimerStack.profile("purchaseItem: ",  
      new UtilTimerStack.ProfilingBlock&lt;String&gt;() { 
           public String doProfiling() { 
              // do some code 
              return "Ok"; 
           } 
      }); 
</pre>
</div></div>

<h2 id="Profiling-ProfilingLogfiles">Profiling Log files</h2>
<p>Profiled result is logged using commons-logging under the logger named <code>com.opensymphony.xwork2.util.profiling.UtilTimerStack</code>. Depending on the underlying logging implementation, say if it is Log4j, one could direct the log to appear in a different file, being emailed to someone or have it stored in the db.</p>

<h2 id="Profiling-Next:">Next: <a shape="rect" href="debugging.html">Debugging</a></h2></div>
        </div>

        
    </div>
</div>
<div class="footer">
    Generated by CXF SiteExporter
</div>
</body>
</html>
